package core

import (
	"reflect"
	"time"
)

// Message tags for Dumbo protocol
const (
	RBCEchoMsgTag    uint8 = iota // RBC Echo message
	RBCReadyMsgTag                // RBC Ready message
	RBCOutputMsgTag               // RBC Output message
	ABABvalMsgTag                 // ABA Bval message
	ABAAuxMsgTag                  // ABA Aux message
	ABAConfMsgTag                 // ABA Conf message
	ABAFinishMsgTag               // ABA Finish message
	MVBAValMsgTag                 // MVBA Val message
	MVBAEchoMsgTag                // MVBA Echo message
	MVBAReadyMsgTag               // MVBA Ready message
	MVBAOutputMsgTag              // MVBA Output message
	PayloadMsgTag                 // Payload message
)

// Node status in Dumbo protocol
const (
	StatusRBC  uint8 = 0 // Running RBC
	StatusABA  uint8 = 1 // Running ABA
	StatusMVBA uint8 = 2 // Running MVBA
)

const STATUSCOUNT = 3

// Basic message structure
type Message struct {
	SN     int    // Sequence number
	Sender int    // Sender ID
	Data   []byte // Message data
}

// RBC (Reliable Broadcast) messages
type RBCEchoMsg struct {
	SN     int
	Sender int
	Data   []byte
	Hash   []byte
}

type RBCReadyMsg struct {
	SN     int
	Sender int
	Hash   []byte
}

type RBCOutputMsg struct {
	SN     int
	Sender int
	Data   []byte
}

// ABA (Asynchronous Binary Agreement) messages
type ABABvalMsg struct {
	SN     int
	Sender int
	Round  int
	Value  int // 0 or 1
}

type ABAAuxMsg struct {
	SN     int
	Sender int
	Round  int
	Value  int // 0 or 1
}

type ABAConfMsg struct {
	SN     int
	Sender int
	Round  int
	Value  int // 0 or 1
}

type ABAFinishMsg struct {
	SN     int
	Sender int
	Value  int // 0 or 1
}

// MVBA (Multi-valued Byzantine Agreement) messages
type MVBAValMsg struct {
	SN     int
	Sender int
	Data   []byte
	Hash   []byte
}

type MVBAEchoMsg struct {
	SN     int
	Sender int
	Hash   []byte
}

type MVBAReadyMsg struct {
	SN     int
	Sender int
	Hash   []byte
}

type MVBAOutputMsg struct {
	SN     int
	Sender int
	Data   []byte
}

// Payload message for transactions
type PayloadMsg struct {
	SN     int
	Sender int
	Txs    [][]byte
}

// Status change signal
type StatusChangeSignal struct {
	SN     int
	Status uint8
}

// Transaction batch
type TxBatch struct {
	SN     int
	Txs    [][]byte
	Size   int
	Hash   []byte
}

// ACS (Asynchronous Common Subset) result
type ACSResult struct {
	SN        int
	Results   [][]byte
	Count     int
	Timestamp time.Time
}

// Create message type instances for reflection
var (
	rbcEchoMsg    = RBCEchoMsg{}
	rbcReadyMsg   = RBCReadyMsg{}
	rbcOutputMsg  = RBCOutputMsg{}
	abaBvalMsg    = ABABvalMsg{}
	abaAuxMsg     = ABAAuxMsg{}
	abaConfMsg    = ABAConfMsg{}
	abaFinishMsg  = ABAFinishMsg{}
	mvbaValMsg    = MVBAValMsg{}
	mvbaEchoMsg   = MVBAEchoMsg{}
	mvbaReadyMsg  = MVBAReadyMsg{}
	mvbaOutputMsg = MVBAOutputMsg{}
	payloadMsg    = PayloadMsg{}
)

// Message type reflection map
var ReflectedTypesMap = map[uint8]reflect.Type{
	RBCEchoMsgTag:    reflect.TypeOf(rbcEchoMsg),
	RBCReadyMsgTag:   reflect.TypeOf(rbcReadyMsg),
	RBCOutputMsgTag:  reflect.TypeOf(rbcOutputMsg),
	ABABvalMsgTag:    reflect.TypeOf(abaBvalMsg),
	ABAAuxMsgTag:     reflect.TypeOf(abaAuxMsg),
	ABAConfMsgTag:    reflect.TypeOf(abaConfMsg),
	ABAFinishMsgTag:  reflect.TypeOf(abaFinishMsg),
	MVBAValMsgTag:    reflect.TypeOf(mvbaValMsg),
	MVBAEchoMsgTag:   reflect.TypeOf(mvbaEchoMsg),
	MVBAReadyMsgTag:  reflect.TypeOf(mvbaReadyMsg),
	MVBAOutputMsgTag: reflect.TypeOf(mvbaOutputMsg),
	PayloadMsgTag:    reflect.TypeOf(payloadMsg),
}

